package com.twq.rules.rule1

/**
 * Created by tangweiqun on 2017/11/18.
 */
trait Group

abstract class SemiGroup[A] extends Group {
  def add(x: A, y: A): A
}

/**
 * 1、一个类型A
 * 2、op(op(x,y), z) == op(x, op(y,z))
 * 3、unit: A
 * op(x, unit) == x
 * op(unit, x) == x
 */
abstract class Monoid[A] extends SemiGroup[A] {
  def unit: A
}

object ImplicitParamRules {

  def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
    if (xs.isEmpty) m.unit
    else m.add(xs.head, sum(xs.tail))


  def main(args: Array[String]): Unit = {

    //1、隐式实体在查找发生的地点可见，并且没有任何的前缀
    //隐式对象
    /*implicit object DoubleMonoidObject extends  Monoid[Double] {

      def add(x: Double, y: Double): Double = x + y

      def unit: Double = 0
    }*/

    //隐式参数
    implicit val doubleMonoidParam = new Monoid[Double] {

      def add(x: Double, y: Double): Double = {
        println("explicit define value")
        x + y
      }

      def unit: Double = 0
    }

    //可以通过import将隐式实体绑定到当前作用域
    //import Implicits._
    //import implicitsOther.doubleMonoid
    println(sum(List(2.0, 4, 5.0)))
  }


}


